import type { Directive } from "vue";

const getInput = (el: HTMLElement): HTMLInputElement | HTMLTextAreaElement | null =>
    el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement
        ? el
        : el.querySelector("input") || el.querySelector("textarea");
function dispatchEvent(el: HTMLElement, type: string) {
    const evt = new Event(type, { bubbles: true, cancelable: true });
    el.dispatchEvent(evt);
}

interface ElType extends HTMLElement {
    inputEle: HTMLInputElement | HTMLTextAreaElement;
    __blurHandler__: () => any;
    __keyHandler__: (event: KeyboardEvent) => any;
}

const trim: Directive = {
    mounted(el: ElType) {
        const inputEle = getInput(el);

        if (!inputEle) return;
        const trimFn = () => {
            const newVal = el.inputEle.value.trim() || "";
            if (el.inputEle.value !== newVal) {
                el.inputEle.value = newVal;
                dispatchEvent(inputEle, "input");
            }
        };

        // 考虑部分回车搜索时尚未失去焦点
        const keydownFn = (event: KeyboardEvent) => {
            if (event.key === "Enter") {
                trimFn();
            }
        };

        el.inputEle = inputEle;
        el.__blurHandler__ = trimFn;
        el.__keyHandler__ = keydownFn;
        inputEle?.addEventListener("blur", trimFn);
        inputEle?.addEventListener("keydown", keydownFn);
    },
    beforeUnmount(el: ElType) {
        el.removeEventListener("blur", el.__blurHandler__);
        el.removeEventListener("keydown", el.__keyHandler__);
    },
};

export default trim;
